#include "btl_config.h"
#include "fp_interrupt_reset.h"
#include "fp_spi.h"
#include "fp_util.h"
#include "fp_log.h"
#include "fp_timer.h"
#include "fp_flash.h"
#include "protocol.h"
#include "fp_algorithm.h"
#include "fp_template.h"
#include "fp_task.h"

#define FINGERPRINT_DEFAULT_SENSOR_ID 0x83112

WORK_STRUCTURE work;

FP_OPT OptGlobal = {
    .MaxEnrollTimes = 8,
};

FP_OPT* fp_option_info(void)
{
    return &OptGlobal;
}

WORK_STRUCTURE* fp_work_info(void)
{
    return &work;
}

#ifdef BTL_SDK_DEBUG
// extern void (*btl_printf)(const char* str, const int ret);
// void fp_algorithm_sdk_debug(const char* s, int a)
// {
//     bf_print_d("[SDK]%s = %d\r\n", s, a);
// }
// btl_printf = printf;
#endif

void fp_algorithm_init(void)
{

    u8 result = 0;
    u8 i = 0;
    u32 Sensor_ID = 0;

    BEP_INIT_PARAM blInitParam = {0};
    btl_storage_setting_t storage_setting = {0};
    BTL_PARAM AlgSensorParam = {0};
    // int pFingerprintImage_len             = fp_chipid_get_size(FINGERPRINT_DEFAULT_SENSOR_ID);
    // uint8_t* pFingerprintImage            = OBTAIN_BODY(pFingerprintImage_len);

#if 1
    btl_printf = printf;
    // btl_get_config()->log_switch = 0xff;
#endif

    blInitParam.rstn_set      = fp_reset_pull;      // in sensor RESET pin
    blInitParam.spi_cs_set    = fp_spi_cs;          // in SPI CS
    blInitParam.spi_send_byte = fp_spi_send_byte;   // in SPI send byte
    blInitParam.spi_rev_byte  = fp_spi_receive;     // in SPI receive byte
    blInitParam.delay_ms      = fp_timer_delay_ms;  // in delay ms
    blInitParam.delay_us      = fp_timer_delay_us;  // in delay us
    blInitParam.pImage        = NULL;               // out fingerprint image

    // bf_print_d("xxxxx");

    for (i = 0; i < 5; i++) {
        bf_print_d("xxxxx: %d", i);
        result = btl_bep_init(&blInitParam);
        bf_print_d("btl_bep_init: %d - %d", i, result);
        if (0 == result)
            break;
    }

    // bf_print_d("btl_bep_init---: %d", result);
    bf_print_d("btl sdk version : %s", btl_get_version());

    if (0 != result) {
        bf_print_d("btl_bep_init---fail");
        return;
    }

    Sensor_ID      = btl_get_sensor_id();
    AlgSensorParam = btl_get_param();
    bf_print_d("Fingerprint sendor_id:%x, default sensor_id:%x", Sensor_ID,
          FINGERPRINT_DEFAULT_SENSOR_ID);
    if (Sensor_ID != FINGERPRINT_DEFAULT_SENSOR_ID) {
        bf_print_d("ERROR!!! Fingerprint sensor_id:%x, default sensor_id:%x", Sensor_ID,
              FINGERPRINT_DEFAULT_SENSOR_ID);
        return;
    }

    // bf_print_d("Fingerprint algo --------------> 1");

    AlgSensorParam.max_template_size = TEMPLATE_MAX_SIZE - sizeof(btl_storage_head_t);
    // AlgSensorParam.support_360rotate           = 1;
    // AlgSensorParam.lock_templates_after_enroll = 1;
    btl_set_param = btl_set_param_cardo;
    btl_set_param(&AlgSensorParam);

    /* Enroll Overlap */
    // TEnrollOverlapParam overlap = btl_get_enroll_overlap_param();
//    overlap.duplicate_min_distance = 0;
//    btl_set_enroll_overlap_param(&overlap);

    // bf_print_d("Fingerprint algo --------------> 2");

    //    btl_get_config()->FingerUpdetect = 1;
    btl_get_config()->nFarAccepted -= 6;
    btl_get_config()->update_FAR_level = btl_get_config()->nFarAccepted + 1;
    btl_get_config()->nEnrollCounts = OptGlobal.MaxEnrollTimes;
    // btl_get_config()->finger_detect_preriod = BTL_50MS_3_3V;
    // btl_get_config()->nVerifyTimeOut = 900;
    // btl_get_config()->image_quality_for_enroll.min_condition = 20;
    // btl_get_config()->image_quality_for_enroll.min_quality = 20;

    /* 3. Fingerprint storage config structure */
    // storage_setting.convert_to_flash_read_addr = NULL;  // 读和写地址一致，不需要转换
    storage_setting.jump_flash_addr                = NULL;  // 地址空间连续，不需要转换
    storage_setting.external_invalidate_flash_data = fp_flash_erase;
    storage_setting.external_write_flash           = fp_flash_write;

    storage_setting.base_flash_addr_for_template = 0;
    storage_setting.storage_size_per_template    = TEMPLATE_MAX_SIZE;
    storage_setting.define_max_nbr_of_templates  = TEMPLATE_MAX_FINGERS;
    storage_setting.added_nbr_of_templates       = ADDED_FP_TEMPLATE_COUNT;
    storage_setting.max_verify_count_one_time    = 5;  // RAM足够大，不需要分批比对

    storage_setting.base_flash_addr_for_other_info = OTHER_INFO_BASE_ADDR;
    storage_setting.flash_size_for_other_info      = OTHER_INFO_SIZE;

    storage_setting.template_id_start_number = 0;
    storage_setting.switch_flag =
        (BSCF_LOCK_ENROLL_TEMPLATES | BSCF_COMPLETE_ENROLL_TEMPLATE_FIRST);

    btl_storage_is_xip_accessible = fp_flash_is_xip_accessible;
	btl_storage_read_flash = fp_flash_read;

    // bf_print_d("Fingerprint algo --------------> 3");

    result = btl_storage_init(storage_setting);
    if (result != BTL_RC_OK) {
        bf_print_d("btl_storage_init fail:%d \n", result);
    }

    // DEBUG("Fingerprint algo --------------> 4");
    btl_storage_set_max_vip_count(2);  // 设置VIP模板数量

    // btl_storage_remove_all_template();

    // fp_template_load();

    // DEBUG("Fingerprint algo --------------> 5");

    // btl_set_work_mode(BTL_VERIFY_MODE);
    fp_do_idle();
 

    // DEBUG("Fingerprint algo --------------> 6");
    // task_run(TASK_ID_IDLE, do_idle);
    // DEBUG("Fingerprint algo --------------> 7");
#ifdef __DEBUG_LOG__
    {
        int w, h;
        w = btl_get_image_width();
        h = btl_get_image_height();
        bf_print_d("%d x %d = %d", w, h, w * h);
    }
#endif /* __DEBUG_LOG__ */

    // DEBUG("Fingerprint algo --------------> 8");
}